package com.nuo.backend.modules.security.service.impl;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.StrUtil;
import com.google.code.kaptcha.Producer;
import com.nuo.backend.common.exception.GlobalException;
import com.nuo.backend.common.utils.*;
import com.nuo.backend.modules.shiro.entity.SysCaptchaEntity;
import com.sun.javafx.binding.StringConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuo.backend.modules.security.dao.SecCaptchaDao;
import com.nuo.backend.modules.security.entity.SecCaptchaEntity;
import com.nuo.backend.modules.security.service.SecCaptchaService;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@Slf4j
@Service("secCaptchaService")
public class SecCaptchaServiceImpl extends ServiceImpl<SecCaptchaDao, SecCaptchaEntity> implements SecCaptchaService {

    @Autowired
    private Producer producer;
    @Autowired
    private RedisUtils redisUtils;

    @Override
    public BufferedImage getCaptchaImg(HttpServletRequest request, String uuid) {
        if(StringUtils.isBlank(uuid)){
            throw new GlobalException("uuid不能为空");
        }
        //生成文字验证码
        String code = producer.createText();

        // TODO Redis
        redisUtils.set(Constant.SEC_UUID_KEY + uuid, code, 300);

        // TODO session
        request.getSession().setAttribute("code", code);

        // TODO MySQL
        SecCaptchaEntity captchaEntity = new SecCaptchaEntity();
        captchaEntity.setUuid(uuid);
        captchaEntity.setCode(code);
        log.info("uuid: " + uuid);
        log.info("code: " + code);

        //5分钟后过期
        captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 5));

        this.save(captchaEntity);

        return producer.createImage(code);
    }

    @Override
    public String captchaStr(HttpServletRequest request, String uuid) {
        if(StringUtils.isBlank(uuid)){
            throw new GlobalException("uuid不能为空");
        }

        // TODO 生成文字验证码
        String code = producer.createText();

        String base64Img;
        try {
            BufferedImage image = producer.createImage(code);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "jpg", outputStream);
            base64Img = "data:image/jpeg;base64," + Base64Encoder.encode(outputStream.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException("图片生成异常...");
        }

        // TODO Redis
        redisUtils.set(Constant.SEC_UUID_KEY + uuid, code, 300);

        // TODO session
        request.getSession().setAttribute("code", code);

        // TODO MySQL
        SecCaptchaEntity captchaEntity = new SecCaptchaEntity();
        captchaEntity.setUuid(uuid);
        captchaEntity.setCode(code);
        log.info("uuid: " + uuid);
        log.info("code: " + code);

        // TODO 5 分钟后过期
        captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 5));

        this.save(captchaEntity);

        return base64Img;
    }

    @Override
    public boolean validate(String uuid, String code) {
        if (StrUtil.isBlank(code)) {
            return false;
        }

        // TODO Redis
        String rCode = redisUtils.get(Constant.SEC_UUID_KEY + uuid);
        if (rCode != null && rCode.equalsIgnoreCase(code)) {
            redisUtils.delete(Constant.SEC_UUID_KEY + uuid);
            return true;
        }

        // TODO MySQL
        SecCaptchaEntity captchaEntity = this.getOne(new QueryWrapper<SecCaptchaEntity>().eq("uuid", uuid));
        if(captchaEntity == null){
            return false;
        }

        //删除验证码
        this.removeById(uuid);

        if (captchaEntity.getCode().equalsIgnoreCase(code) && captchaEntity.getExpireTime().getTime() >= System.currentTimeMillis()){
            return true;
        }

        return false;
    }

}